#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

void test1()
{
  FILE* fp = fopen("test.txt", "w+");   // 使用绝对路径来进行查找，读写操作，没有会进创建对应文件，有会将其数据清空
  const char* ptr = "你好, Linux!\n"; // 输入我们想要写入的字符串
  //write(ptr, 1, strlen(ptr), fp);  // 输出字符串 每个数据大小 多少个数据 目标写入文件
  fprintf(fp,"%s", ptr);
  fclose(fp);  // 不要忘记关闭文件哦
}

void test2()
{
  const char* ptr = "你好, Linux!\n";
  fprintf(stdout, "%s", ptr);
}

#define S_GOOD 0x1  // 学生好选项
#define T_GOOD 0x2  // 老师好选项
#define L_GOOD 0x4  // 领导好选项

void test3(int flag)
{
  if (flag & 0x1) printf("学生好\n");  // 001
  if (flag & 0x2) printf("老师好\n");  // 010
  if (flag & 0x4) printf("领导好\n");  // 100 
}

void test4()
{
  printf("----------------------------\n");
  test3(S_GOOD);
  printf("----------------------------\n");
  test3(T_GOOD);
  printf("----------------------------\n");
  test3(L_GOOD);
  printf("----------------------------\n");
  test3(S_GOOD | T_GOOD);
  printf("----------------------------\n");
  test3(S_GOOD | L_GOOD);
  printf("----------------------------\n");
  test3(S_GOOD | T_GOOD | L_GOOD);
  printf("----------------------------\n");
}

void test5()
{
  int fd = open("test.txt", O_RDWR | O_CREAT | O_TRUNC, 0666);  // 可读可写 没有此文件创建 打开文件前清空 文件访问权限（最后和掩码要过滤
  if (fd < 0)
  {
    perror("open error");
    return;
  }
  const char* buf = "i like Linux!\n";
  ssize_t ret = write(fd, buf, strlen(buf));  // 文件描述符 字符缓冲区 写入的字节数大小
  if (ret < 0 )
  {
    perror("write error");
    return;
  }
  // 写入后开始读入要求从头开始，此时偏移量为上次写入的最后位置，所以需要用到修正偏移lssek
  lseek(fd, 0, SEEK_SET);  // 0 从头开始
  char buff[1024] = {0};
  ret = read(fd, buff, 1023);  // 保证最后为\0 实际上没有1023个字节的数据 读完即可
  if (ret < 0)
  {
    perror("read error");
    return;
  }
  else if (ret == 0)
  {
    printf("end of file\n");  // 读入了0个字符
    return;
  }
  printf("%s\n", buff);
  close(fd);  // 关闭文件

}

void test6()
{
  int fd1 = open("test.txt", O_RDWR | O_CREAT | O_TRUNC, 0664);
  int fd2 = open("test1.txt", O_RDWR | O_CREAT | O_TRUNC, 0664);
  int fd3 = open("test2.txt", O_RDWR | O_CREAT | O_TRUNC, 0664);
  printf("%d\n", fd1);
  printf("%d\n", fd2);
  printf("%d\n", fd3);
  close(fd1);
  close(fd2);
  close(fd3);
}

void test7()
{
  printf("%d\n", stdin->_fileno);
  printf("%d\n", stdout->_fileno);
  printf("%d\n", stderr->_fileno);
}

void test8()
{
  close(1);
  int fd = open("test.txt", O_RDWR | O_CREAT | O_TRUNC, 0666);
  if (fd < 0)
  {
    perror("open error");
    return;
  }
  printf("Linux nice!\n");
  fflush(stdout);
  close(fd);
}
void test9()
{
  close(1);
  int fd = open("test.txt", O_WRONLY | O_CREAT | O_APPEND, 0666);
  if (fd < 0)
  {
    perror("open error\n");
    return;
  }
  printf("谢谢你！Linux！\n");
  fflush(stdout);
  close(fd);
}
void test10()
{
  // 输出重定向
  int fd = open("test.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
  dup2(fd, 1);  // 让fd指向的文件，重定向到1指向的位置，即让1也指向fd所指向的文件
  printf("dup2 test\n");
  close(fd);
}
void test11()
{
  // 追加重定向
  int fd = open("test.txt", O_WRONLY | O_CREAT | O_APPEND, 0666);
  dup2(fd, 1);  // 让fd指向的文件，重定向到1指向的位置，即让1也指向fd所指向的文件
  printf("dup2 Linux\n");
  close(fd);
}
int main()
{
  test11();
  return 0;
}
